timsort: Add progress estimation
authorBenjamin Otte <otte@redhat.com>
Sun, 12 Jul 2020 15:57:03 +0000 (17:57 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 22 Jul 2020 12:30:49 +0000 (14:30 +0200)
gtk/gtktimsort.c
gtk/gtktimsortprivate.h

index 4ddb6c92457f274c960f728e1d2a3f86be4445f8..548bb292b595a2529c93351cd28513ecb90649be 100644 (file)
@@ -266,6 +266,51 @@ gtk_tim_sort_set_max_merge_size (GtkTimSort *self,
   self->max_merge_size = max_merge_size;
 }
 
+/**
+ * gtk_tim_sort_get_progress:
+ * @self: a #GtkTimSort
+ *
+ * Does a progress estimate about sort progress, estimates relative
+ * to the number of items to sort.
+ *
+ * Note that this is entirely a progress estimate and does not have
+ * a relationship with items put in their correct place.  
+ * It is also an estimate, so no guarantees are made about accuracy,
+ * other than that it will only report 100% completion when it is
+ * indeed done sorting.
+ *
+ * To get a percentage, you need to divide this number by the total
+ * number of elements that are being sorted.
+ *
+ * Returns: Rough guess of sort progress
+ **/
+gsize
+gtk_tim_sort_get_progress (GtkTimSort *self)
+{
+#define DEPTH 4
+  gsize i;
+  gsize last, progress;
+
+  g_return_val_if_fail (self != NULL, 0);
+
+  if (self->pending_runs == 0)
+    return 0;
+
+  last = self->run[0].len;
+  progress = 0;
+
+  for (i = 1; i < DEPTH + 1 && i < self->pending_runs; i++)
+    {
+      progress += (DEPTH + 1 - i) * MAX (last, self->run[i].len);
+      last = MIN (last, self->run[i].len);
+    }
+  if (i < DEPTH + 1)
+    progress += (DEPTH + 1 - i) * last;
+
+  return progress / DEPTH;
+#undef DEPTH
+}
+
 #if 1
 #define WIDTH 4
 #include "gtktimsort-impl.c"
index a864a9c9364a314e411beca05b975cb9f48ca10d..1fcadbd9a6f9703289cbf03bf9ec29d9e312c341 100644 (file)
@@ -108,6 +108,8 @@ void            gtk_tim_sort_set_runs                           (GtkTimSort
 void            gtk_tim_sort_set_max_merge_size                 (GtkTimSort             *self,
                                                                  gsize                   max_merge_size);
 
+gsize           gtk_tim_sort_get_progress                       (GtkTimSort             *self);
+
 gboolean        gtk_tim_sort_step                               (GtkTimSort             *self,
                                                                  GtkTimSortRun          *out_change);